package com.sinsz.pay.factory;

import com.sinsz.common.exception.ApiException;
import com.sinsz.pay.properties.PayProperties;
import com.sinsz.pay.support.Constant;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import static com.sinsz.pay.properties.support.WeChatPlatform.PUBLIC;

/**
 * 支付抽象方法
 * @author chenjianbo
 */
public abstract class BasePay implements Pay {

    private PayProperties prop;

    public BasePay(PayProperties prop) {
        this.prop = prop;
    }

    public PayProperties getProp() {
        return prop;
    }

    public void setProp(PayProperties prop) {
        this.prop = prop;
    }

    protected String formatOutTradeNo(String outTradeNo) {
        if (StringUtils.isEmpty(outTradeNo)) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失自定义商户订单号");
        }
        return outTradeNo;
    }

    protected String formatBody(String body) {
        if (StringUtils.isEmpty(body)) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失订单描述信息");
        }
        return body;
    }

    protected String formatDetail(String body, String detail) {
        return StringUtils.isEmpty(detail) ? formatBody(body) : detail;
    }

    protected int formatFee(int fee) {
        if (fee <= 0 || fee > 500000) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"付款金额不合法，金额范围为：0.01~5000元人民币");
        }
        return fee;
    }

    protected int formatTransferFee(int fee) {
        if (fee < 100 || fee > 2000000) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"付款金额不合法，金额范围为：1~20000元人民币");
        }
        return fee;
    }

    protected int formatRefundFee(int total, int fee) {
        total = formatFee(total);
        if (fee <= 0 || fee > 500000) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"付款金额不合法，金额范围为：0.01~5000元人民币");
        }
        if (fee > total) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"退款金额溢出可退款金额");
        }
        return fee;
    }

    protected String formatOpenid(String openid) {
        if (PUBLIC.equals(prop.getWxpay().getPlatform())) {
            if (StringUtils.isEmpty(openid)) {
                throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"请先获取公众号授权openid(或填写支付宝用户收款账号)");
            }
        }
        return StringUtils.isEmpty(openid) ? "" : openid;
    }

    protected String formatTradeType() {
        switch (prop.getWxpay().getPlatform()) {
            case PUBLIC:
                return "JSAPI";
            case OPEN:
                return "APP";
            default:
                throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"微信交易类型不存在");
        }
    }

    protected String formatMoney(int fee) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        return decimalFormat.format(fee / 100f);
    }

    protected String formatOutRefundNo(String outRefundNo) {
        if (StringUtils.isEmpty(outRefundNo)) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失自定义商户退款订单号");
        }
        return outRefundNo;
    }

    protected String formatBillDate(Date date) {
        if (date == null) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失对账日期");
        }
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("Asia/Shanghai")).toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }

    protected String formatAliBillDate(Date date) {
        if (date == null) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失对账日期");
        }
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("Asia/Shanghai")).toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    protected String formatNotifyParams(HttpServletRequest request) {
        try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
            InputStream is = request.getInputStream()) {
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            return new String(baos.toByteArray(),"UTF-8");
        } catch (IOException e) {
            e.printStackTrace(System.out);
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"回调参数解析异常");
        }
    }

    protected String formatPartnerTradeNo(String partnerTradeNo) {
        if (StringUtils.isEmpty(partnerTradeNo)) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失自定义商户打款订单号");
        }
        return partnerTradeNo;
    }

    protected String formatUserName(String userName) {
        if (StringUtils.isEmpty(userName)) {
            throw new ApiException(Constant.DEFAULT_EXCEPTION_CODE,"缺失用户真实姓名");
        }
        return userName;
    }


}
